using System.Linq;
using complex.Domain;
using FubuMVC.Core.Continuations;
using NHibernate;

namespace complex.Controllers.Customers
{
    public class CustomerController
    {
        private readonly ISession session;

        public CustomerController(ISession session)
        {
            this.session = session;
        }

        public PageOfCustomersOutputModel List(ViewCustomersInputModelQuery input)
        {
            var customers = session
                .QueryOver<Customer>()
                .OrderBy(customer => customer.Name).Asc
                .Skip(input.StartAt())
                .Take(input.ItemsPerPage)
                .Future<Customer>()
                .Select(customer => new CustomerSummaryOutputModel
                                        {
                                            Id = customer.Id,
                                            Name = customer.Name,
                                            BillingAddress = customer.Address.ToString()
                                        });

            var totalCustomerss = session
                .QueryOver<Customer>()
                .ToRowCountQuery()
                .FutureValue<int>();

            return new PageOfCustomersOutputModel
                       {
                           Items = customers.ToArray(),
                           Total = totalCustomerss.Value,
                           PageSize = input.ItemsPerPage,
                           CurrentPage = input.Page,
                       };
        }

        [SkipTransaction]
        public NewCustomerOutputModel New(NewCustomerInputModelQuery input)
        {
            return new NewCustomerOutputModel();
        }

        public FubuContinuation Add(NewCustomerInputModelCommand input)
        {
            var customer = new Customer
                               {
                                   Name = input.Name,
                                   Address = new Address
                                                 {
                                                     Line1 = input.Line1,
                                                     City = input.City,
                                                     State = input.State,
                                                     ZipCode = input.ZipCode
                                                 }
                               };

            session.Save(customer);

            return FubuContinuation.RedirectTo(new ViewCustomersInputModelQuery());
        }

        public EditCustomerOutputModel View(EditCustomerInputModelQuery input)
        {
            var customer = session.Get<Customer>(input.Id);
            return new EditCustomerOutputModel
                       {
                           Id = customer.Id,
                           Name = customer.Name,
                           Line1 = customer.Address.Line1,
                           City = customer.Address.City,
                           State = customer.Address.State,
                           ZipCode = customer.Address.ZipCode,
                       };
        }

        public FubuContinuation Update(EditCustomerInputModelCommand input)
        {
            var customer = session.Get<Customer>(input.Id);
            customer.Name = input.Name;
            customer.Address = new Address
                                   {
                                       Line1 = input.Line1,
                                       City = input.City,
                                       State = input.State,
                                       ZipCode = input.ZipCode
                                   };

            return FubuContinuation.RedirectTo(new ViewCustomersInputModelQuery());
        }

        public FubuContinuation Delete(RemoveCustomerInputModelCommand input)
        {
            var customer = session.Load<Customer>(input.Id);
            session.Delete(customer);

            return FubuContinuation.RedirectTo(new ViewCustomersInputModelQuery());
        }
    }
}